package io.github.harmonly.skyblock.game.scoreboard;

import com.google.gson.JsonArray;
import io.github.harmonly.skyblock.data.ProfileData;
import io.github.harmonly.skyblock.manager.DataManager;
import io.github.harmonly.skyblock.manager.ResourcesManager;
import io.github.harmonly.skyblock.util.Scheduler;
import io.github.harmonly.skyblock.util.StableObject;
import io.github.harmonly.skyblock.util.TimeHelper;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitTask;
import org.bukkit.scoreboard.*;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Optional;

public class Sidebar {

    private final Scoreboard scoreboard;
    private final Player player;
    private final Optional<ProfileData> profileDataOptional;
    private Objective sidebar;
    private BukkitTask task;

    public Sidebar(Player player) {
        this.scoreboard = player.getScoreboard();
        this.player = player;
        this.profileDataOptional = DataManager.getProfileData(player);
        sidebar = scoreboard.getObjective("SIDEBAR");
        if (sidebar == null) {
            sidebar = scoreboard.registerNewObjective(
                    "SIDEBAR",
                    Criteria.DUMMY,
                    "§e§lSKYBLOCK");
        }
        sidebar.setDisplaySlot(DisplaySlot.SIDEBAR);
        for (int i = 1; i <= 15; ++i) {
            Team team = scoreboard.getTeam("SLOT_" + i);
            if (team == null) {
                team = scoreboard.registerNewTeam("SLOT_" + i);
            }
            team.addEntry(getEntry(i));
        }
        task = Scheduler.runTaskTimer(this::load, 0L, 20L);
    }

    public void disable() {
        task.cancel();
        scoreboard.clearSlot(DisplaySlot.SIDEBAR);
        scoreboard.clearSlot(DisplaySlot.BELOW_NAME);
    }

    private void load() {
        setSlot(9, "§7" + getRealDate());
        setSlot(8, "  ");
        setSlot(7, " " + getCustomSeason());
        setSlot(6, " §7" + getCustomHour());
        setSlot(5, " §7⏣ §b" + getZone());
        setSlot(4, "   ");
        setSlot(3, getCustomPurse());
        setSlot(2, " ");
        setSlot(1, "§ewww.hypixel.net");

        profileDataOptional.ifPresent(profileData -> {
            profileData.updatePrefix();
            profileData.addPurse(Math.random() * Math.random() * 100);
        });
    }

    private void setSlot(int slot, String text) {
        Team team = scoreboard.getTeam("SLOT_" + slot);
        if (team == null) return;

        String entry = getEntry(slot);
        if (!scoreboard.getEntries().contains(entry)) {
            sidebar.getScore(entry).setScore(slot);
        }

        StringBuilder pre = new StringBuilder(text.substring(0, text.length() / 2));
        StringBuilder suf = new StringBuilder(text.substring(text.length() / 2));
        if (pre.length() > 0 && pre.charAt(pre.length() - 1) == '§') {
            pre.deleteCharAt(pre.length() - 1);
            suf.insert(0, '§');
        }
        team.setPrefix(pre.toString());
        team.setSuffix(ChatColor.getLastColors(pre.toString()) + suf);
    }

    private void removeSlot(int slot) {
        String entry = getEntry(slot);
        if (scoreboard.getEntries().contains(entry))
            scoreboard.resetScores(entry);
    }

    private String getEntry(int slot) {
        return ChatColor.values()[slot].toString();
    }

    public static String getRealDate() {
        StableObject json = ResourcesManager.getJson("time");
        return new SimpleDateFormat(json.getStringProperty("real_date_pattern", "MM/dd/yy"))
                .format(new Date());
    }

    public static String getCustomSeason() {
        return "§f" + calculateSeason(TimeHelper.getMonth() - 1) + ' ' + getDayWithSuffix(TimeHelper.getDay());
    }

    public static String getCustomHour() {
        int hour = TimeHelper.getHour();
        String period = hour >= 12 ? "pm" : "am";
        String icon = 6 <= hour && hour <= 19 ? "§e☀" : "§b☽";

        // 将小时转换为12小时格式
        if (hour == 0) {
            hour = 12;
        } else if (hour > 12) {
            hour -= 12;
        }
        return String.format("%d:%02d%s %s", hour, TimeHelper.getMinutes() / 10 * 10, period, icon);
    }

    /**
     * 根据月份计算季节和时段
     */
    private static String calculateSeason(int month) {
        StableObject json = ResourcesManager.getJson("time");
        JsonArray season = json.getArrayProperty("season");
        if (season.isJsonNull()) {
            return json.getStringProperty("unknown_season", "UNKNOWN");
        }
        return season.get(month).getAsString();
    }

    /**
     * 获取日期的正确英文后缀
     */
    private static String getDayWithSuffix(int day) {
        if (day >= 11 && day <= 13) {
            return day + "th";
        }
        return switch (day % 10) {
            case 1 -> day + "st";
            case 2 -> day + "nd";
            case 3 -> day + "rd";
            default -> day + "th";
        };
    }

    public String getCustomPurse() {
        String s = "§fPurse: §6";
        if (profileDataOptional.isPresent()) {
            ProfileData profileData = profileDataOptional.get();
            s += purseFormat(profileData.getPurse());

            StableObject playingData = profileData.getPlayingData();
            double increasedAmount = playingData.getDoubleProperty("coin_purse_increased_amount", 0);
            if (increasedAmount > 0) {
                s += " §e(+" + purseFormat(increasedAmount) + ")";
                playingData.removeProperty("coin_purse_increased_amount");
            }
            return s;
        } else {
            s += '0';
        }
        return s;
    }

    private String purseFormat(double purse) {
        if (purse < 1000) {
            return String.format("%.1f", purse);
        }
        return new DecimalFormat("###,###").format(purse);
    }

    public String getZone() {
        String name = player.getWorld().getName();
        if (name.contains("island")) {
            return "§aYour Island";
        }
        return name.substring(name.lastIndexOf('/') + 1);
    }
}
